
#include <cassert>
#include <error.h>
#include <string.h>
#include "AppendFile.hpp"
namespace tulun
{
    // class AppendFile:: // fopen write close
    // static const size_t FILE_BUFF_SIZE = 1024 * 1024 * 10;
    // std::unique_ptr<char[]> *buffer_; // new char[10M];
    // FILE *fp_;
    // size_t writenBytes_;
    size_t AppendFile::write(const char *msg, const size_t len)
    {
        return fwrite(msg, sizeof(char), len, fp_);
        // return fwrite_unlocked(msg, sizeof(char), len, fp_);
    }

    AppendFile::AppendFile(const std::string &filename)
        : buffer_{new char[FILE_BUFF_SIZE]},
          fp_{nullptr},
          writeBytes_{0}
    {
        fp_ = fopen(filename.c_str(), "a");
        assert(fp_ != nullptr);
        setbuffer(fp_, buffer_.get(), FILE_BUFF_SIZE);
    }
    AppendFile::~AppendFile()
    {
        fclose(fp_);
        fp_ = nullptr;
        buffer_.reset();
    }

    void AppendFile::append(const std::string &msg)
    {
        append(msg.c_str(), msg.size());
    }
    void AppendFile::append(const char *msg, const size_t len)
    {
        size_t n = write(msg, len); // len = 1024; n = 256;
        size_t remain = len - n;    // 1024 - 256
        while (remain > 0)
        {
            size_t x = write(msg + n, remain);
            if (x == 0)
            {
                int err = ferror(fp_);
                if (err)
                {
                    fprintf(stderr, "appendfile::append failed %s \n", strerror(err));
                }
            }
            n += x;
            remain = len - n;
        }
        writeBytes_ += n;
    }
    void AppendFile::flush()
    {
        fflush(fp_);
    }
    size_t AppendFile::getWriteBytes() const
    {
        return writeBytes_;
    }

} // namespace tulun